package cn.edu.sdjzu.knoverse.excel;

import cn.edu.sdjzu.knoverse.constant.UserConstant;
import cn.edu.sdjzu.knoverse.model.dto.system.user.AdminUserAddDto;
import cn.edu.sdjzu.knoverse.model.dto.system.user.UserImportExcelDto;
import cn.edu.sdjzu.knoverse.service.UserService;
import cn.edu.sdjzu.knoverse.utils.exception.CustomException;
import cn.edu.sdjzu.knoverse.utils.exception.ExcelDataException;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;

/**
 * Excel用户导入监听器
 */
@Slf4j
public class UserImportListener extends AnalysisEventListener<UserImportExcelDto> {

    private final UserService userService;
    private final Long deptId; // 部门ID
    private final List<AdminUserAddDto> userList = new ArrayList<>();
    private final int BATCH_COUNT = 100; // 批量插入大小
    private int rowIndex = 0; // 行号，用于错误定位

    public UserImportListener(UserService userService, Long deptId) {
        this.userService = userService;
        this.deptId = deptId;
    }

    @Override
    public void invoke(UserImportExcelDto data, AnalysisContext context) {
        rowIndex++;
        try {
            // 数据校验
            validateData(data);
            
            // 转换为AdminUserAddDto
            AdminUserAddDto userDto = convertToUserDto(data);
            userList.add(userDto);
            
            // 达到BATCH_COUNT则批量插入数据库
            if (userList.size() >= BATCH_COUNT) {
                saveUserBatch();
                // 清理list
                userList.clear();
            }
        } catch (ExcelDataException e) {
            throw new ExcelDataException("第" + rowIndex + "行数据错误：" + e.getMessage());
        } catch (Exception e) {
            log.error("Excel导入处理异常", e);
            throw new CustomException("第" + rowIndex + "行数据处理失败：" + e.getMessage());
        }
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
        // 处理剩余数据
        if (!userList.isEmpty()) {
            saveUserBatch();
        }
        log.info("Excel用户导入完成，共导入{}条数据", rowIndex);
    }

    /**
     * 数据校验
     */
    private void validateData(UserImportExcelDto data) {
        if (!StringUtils.hasText(data.getUsername())) {
            throw new ExcelDataException("用户名不能为空");
        }
        if (!StringUtils.hasText(data.getNickname())) {
            throw new ExcelDataException("昵称不能为空");
        }
        if (!StringUtils.hasText(data.getEmail())) {
            throw new ExcelDataException("邮箱不能为空");
        }
    }

    /**
     * 转换为用户DTO
     */
    private AdminUserAddDto convertToUserDto(UserImportExcelDto data) {
        AdminUserAddDto dto = new AdminUserAddDto();
        dto.setUsername(data.getUsername());
        dto.setNickname(data.getNickname());
        dto.setEmail(data.getEmail());
        dto.setPhone(data.getPhone());
        
        // 设置密码，如果Excel没有提供则使用默认值
        if (StringUtils.hasText(data.getPassword())) {
            dto.setPassword(data.getPassword());
        } else {
            dto.setPassword("123456"); // 默认密码
        }
        
        // 设置性别
        if (StringUtils.hasText(data.getSex())) {
            if ("男".equals(data.getSex())) {
                dto.setSex((byte) 1);
            } else if ("女".equals(data.getSex())) {
                dto.setSex((byte) 0);
            } else {
                dto.setSex((byte) 1); // 默认为男
            }
        } else {
            dto.setSex((byte) 1); // 默认为男
        }
        
        // 设置状态
        if (StringUtils.hasText(data.getStatus())) {
            if ("禁用".equals(data.getStatus())) {
                dto.setStatus(true);
            } else if ("启用".equals(data.getStatus())) {
                dto.setStatus(false);
            } else {
                dto.setStatus(false); // 默认为启用
            }
        } else {
            dto.setStatus(false); // 默认为启用
        }
        
        // 设置个人描述
        if (StringUtils.hasText(data.getSummary())) {
            dto.setSummary(data.getSummary());
        } else {
            dto.setSummary(UserConstant.PERSON_DESCRIPTION);
        }
        
        // 设置部门ID
        dto.setDeptId(this.deptId);
        
        return dto;
    }

    /**
     * 批量保存用户
     */
    private void saveUserBatch() {
        try {
            for (AdminUserAddDto userDto : userList) {
                userService.addAdminUser(userDto);
            }
        } catch (Exception e) {
            log.error("批量添加用户失败", e);
            throw new CustomException("批量添加用户失败：" + e.getMessage());
        }
    }
} 